'''
Created on Jul 31, 2011

@author: kafkef
'''


import os

from PyQt4.QtGui import *
from PyQt4.QtCore import SIGNAL, QDir, Qt, QVariant, QSettings, QString, QSize,\
                         QPoint

from dexen.system.client import db
from dexen.system.client import ui
from dexen.system.client.proxy import JobProxy
from dexen.system.client.controller.db_syncher import DBSyncher


job_info = None
svr_info = None
job_proxy = None
svr_proxy = ui.svr_proxy
db_syncher = DBSyncher()


class ArchiveListWidget(QListWidget):
    def __init__(self, parent=None):
        QListWidget.__init__(self, parent)


class ArchiveDialog(QDialog):
    def __init__(self, ind_id, parent):
        super(ArchiveDialog, self).__init__(parent)
        global job_info, svr_info, job_proxy
        
        self.setWindowTitle("Download/Export Archive")
        self.setModal(True)
        job_info = ui.get_job_info()
        svr_info = job_info.get_svr_info()
        self.ind_id = ind_id
        
        self._read_settings()
        self._setup_widgets()     
        self._initialize_content()   
       
    def _setup_widgets(self):
        # Create the widgets
        self.archiveListWdg = ArchiveListWidget() 
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | 
                                          QDialogButtonBox.Cancel)
        self.saveBtn = QPushButton("Save", self)
        self.saveAllBtn = QPushButton("Save All", self)
        self.browseBtn = QPushButton("Browse", self)
        self.browseLineEdit = QLineEdit(self._load_rootdir(), self)
        title = QString("Archive items: Ind %1").arg(self.ind_id)
        self.archiveLabel = QLabel(title, self) 
        self.browseLabel = QLabel("Archive folder:", self)
         
        # Setup layout
        vLayout = QVBoxLayout()

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.browseLabel)
        hLayout.addWidget(self.browseLineEdit)
        hLayout.addWidget(self.browseBtn)
        vLayout.addLayout(hLayout)

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.archiveLabel)
        hLayout.addStretch()
        hLayout.addWidget(self.saveBtn)
        hLayout.addWidget(self.saveAllBtn)
        vLayout.addLayout(hLayout)
        
        vLayout.addWidget(self.archiveListWdg)                
        self.setLayout(vLayout)
        
        # Configure the signal/slots connections
        self.connect(self.saveBtn, SIGNAL("clicked()"), self.on_save)
        self.connect(self.saveAllBtn, SIGNAL("clicked()"), self.on_save_all)
        self.connect(self.browseBtn, SIGNAL("clicked()"), self.on_browseBtn_clicked)
        
    def _initialize_content(self):
        job_id = job_info.get_id() 
        svr_info = job_info.get_svr_info()
        assert isinstance(svr_info, db.ServerInfo)
        
        archive_names = []
        if not svr_info.is_connected():
            archive_names = db_syncher.get_ind_archive_names(self.ind_id, 
                                                             job_id, svr_info)
        else:
            jobProxy = svr_proxy.get_job_proxy(job_id)
            assert isinstance(jobProxy, JobProxy)
            archive_names = jobProxy.get_ind_archive_names(self.ind_id)
            print "archive_names: ", archive_names
        
        for name in archive_names:
            item = QListWidgetItem(name)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            self.archiveListWdg.addItem(item)

    def get_content(self, archive_name):
        assert isinstance(job_info, db.JobInfo)
        content = db_syncher.get_ind_archive(self.ind_id, archive_name, 
                                             job_info.get_id(), svr_info)
        
        if content is None and svr_info.is_connected():
            job_proxy = svr_proxy.get_job_proxy(job_info.get_id())
            assert isinstance(job_proxy, JobProxy)
            content = job_proxy.get_ind_archive(self.ind_id, archive_name)
            db_syncher.persist_ind_archive(self.ind_id, archive_name, content, 
                                           job_info.get_id(), svr_info)
        
        return content

    def on_save_all(self):
        self.on_save(True)

    def on_save(self, isAll=False):
        list_widget = self.archiveListWdg
        assert isinstance(list_widget, QListWidget)
        
        rootdir = str(self.browseLineEdit.text())
        for i in xrange(list_widget.count()):
            item = list_widget.item(i)
            assert isinstance(item, QListWidgetItem)
            if isAll or (item.checkState() & Qt.Checked):
                archive_name = str(item.text())
                content = self.get_content(archive_name)
                if content is not None:
                    ind_dirname = "Ind_{0}".format(self.ind_id)
                    inddir = os.path.join(rootdir, ind_dirname)
                    if not os.path.exists(inddir):
                        os.mkdir(inddir)
                    f = open(os.path.join(inddir, archive_name), "wb")
                    f.write(content)
                    f.close()    
    
    def on_browseBtn_clicked(self):
        rootdir = QFileDialog.getExistingDirectory(self, "Choose Directory",
                                                   self._load_rootdir(),
                                                   QFileDialog.ShowDirsOnly)
        if not os.path.exists(str(rootdir)): return        
        self.browseLineEdit.setText(rootdir)
        self._save_rootdir(rootdir)        
    
    def _load_rootdir(self):
        settings = QSettings()
        rootdir = settings.value("ArchiveDlg/RootDir", 
                                 QVariant(QDir.rootPath())).toString()
        if not os.path.exists(rootdir):
            return QDir.rootPath()    
        return rootdir
    
    def _save_rootdir(self, rootdir):
        settings = QSettings()
        rootdir = settings.setValue("ArchiveDlg/RootDir", rootdir) 

    def _read_settings(self):
        settings = QSettings()
        app_pos = qApp.activeWindow().pos()
        app_size = qApp.activeWindow().size()
        assert isinstance(app_pos, QPoint)
        assert isinstance(app_size, QSize)
        
        size = settings.value("ArchiveDlg/Size", QVariant(QSize(500, 300))).toSize()
        default_pos = QPoint()
        default_pos.setX(app_pos.x() + app_size.width()/2 - size.width()/2)
        default_pos.setY(app_pos.y() + app_size.height()/2 - size.height()/2)
        pos = settings.value("ArchiveDlg/Pos", QVariant(default_pos)).toPoint()
        
        self.resize(size)
        self.move(pos)
    
    def _write_settings(self):
        settings = QSettings()
        settings.setValue("ArchiveDlg/Pos", self.pos())
        settings.setValue("ArchiveDlg/Size", self.size())
        
    def closeEvent(self, event):
        self._write_settings()
        event.accept()

